/*
 * Punto.cpp
 *
 *  Created on: 27/09/2009
 *      Author: ale
 */

#include "Punto.h"
#include <cmath>

Punto::Punto(float x, float y, float z) {
	coordenada[0] = x;
	coordenada[1] = y;
	coordenada[2] = z;
}

Punto::Punto(const Punto& otro) {
	coordenada[0] = otro.coordenada[0];
	coordenada[1] = otro.coordenada[1];
	coordenada[2] = otro.coordenada[2];
}
Punto& Punto::operator=(const Punto& otro) {
	coordenada[0] = otro.coordenada[0];
	coordenada[1] = otro.coordenada[1];
	coordenada[2] = otro.coordenada[2];
	return *this;
}

Punto Punto::operator-(const Punto& otro){
	Punto temp;
	temp.x(this->coordenada[0] -otro.x());
	temp.y(this->coordenada[1] -otro.y());
	temp.z(this->coordenada[2] -otro.z());
	return temp;
}

Punto::~Punto() {
}

float Punto::operator[](int i){
	return coordenada[i % 3];
}

float Punto::x() const {
	return coordenada[0];
}

float Punto::y() const {
	return coordenada[1];
}

float Punto::z() const {
	return coordenada[2];
}

void Punto::x(float newX) {
	coordenada[0] = newX;
}

void Punto::y(float newY) {
	coordenada[1] = newY;
}

void Punto::z(float newZ) {
	coordenada[2] = newZ;
}

void Punto::setXYZ(float x, float y, float z) {
	coordenada[0] = x;
	coordenada[1] = y;
	coordenada[2] = z;
}

bool Punto::operator==(const Punto& otro){
	return ((coordenada[0] == otro.coordenada[0]) &&
			(coordenada[1] == otro.coordenada[1]) &&
			(coordenada[2] == otro.coordenada[2]));
}

std::ostream& operator<<(std::ostream& out, const Punto& punto) {
	out << "( " << punto.x() << " , " << punto.y() << " , " << punto.z()
			<< " )";
	return out;
}


/*        p
 *        --->
 *   this|          this x p
 *       V
 * */
Punto Punto::productoVectorial(const Punto& p){
		Punto n;
		n.x(((this->y()*p.z())-(this->z()*p.y())));
		n.y(-((this->x()*p.z())-(this->z()*p.x())));
		n.z(((this->x()*p.y())-(this->y()*p.x())));
		return n;
}



float Punto::modulo()const{
	return sqrt(  pow(this->x(),2) + pow(this->y(),2) + pow(this->z(),2)  );
}

/*
 * Radianes:
 *
 *        ---> p
 * this  | o = arcos( this.p /|this|.|p|)
 *       V
 * */

float Punto::anguloCon(const Punto&p){
	return acos( ( this->x()*p.x() + this->y()*p.y() + this->z()*p.z() )/(this->modulo() * p.modulo()) );
}
